package engine.data;

import java.io.IOException;

import javax.microedition.lcdui.Image;

public final class TerrainType {

	public static final byte UNDEFINED = -1;

	public static final byte ARTIC = 0;

	public static final byte DESERT = 1;

	public static final byte FOREST = 2;

	public static final byte GRASSLAND = 3;

	public static final byte HILL = 4;

	public static final byte JUNGLE = 5;

	public static final byte MOUNTAINS = 6;

	public static final byte OCEAN = 7;

	public static final byte PLAINS = 8;

	public static final byte RIVERS = 9;

	public static final byte SWAMP = 10;

	public static final byte TUNDRA = 11;

	// SPECIAL RESOURCES
	public static final byte COAL = 12;

	public static final byte FISH = 13;

	public static final byte GAME_FOREST = 14;

	public static final byte GAME_TUNDRA = 15;

	public static final byte GEMS = 16;

	public static final byte GOLD = 17;

	public static final byte HORSES = 18;

	public static final byte OASIS = 19;

	public static final byte OIL = 20;

	public static final byte SEALS = 21;

	// IRRIGATION
	public static final byte DESERT_I = 22;

	public static final byte GRASSLAND_I = 23;

	public static final byte HILLS_I = 24;

	public static final byte PLAINS_I = 25;

	public static final byte RIVERS_I = 26;

	public static final byte COALS_I = 27;

	public static final byte HORSES_I = 28;

	public static final byte OASIS_I = 29;

	// MINING
	public static final byte DESERT_M = 30;

	public static final byte HILLS_M = 31;

	public static final byte MOUNTAINS_M = 32;

	public static final byte GOLD_M = 33;

	public static final byte OASIS_M = 34;

	public static final byte COAL_M = 35;

	public static final byte SIZE = 36;

	// movement cost
	private static final byte[] MOVEMENT_COST = new byte[] { 2, 1, 2, 1, 2, 2, 3, 1, 1, 1, 2, 1, 2, 1, 2, 1, 2, 3, 1,
			1, 2, 2, 1, 1, 2, 1, 1, 2, 1, 1, 1, 2, 3, 3, 1, 2 };

	// defense bonus
	private static final short[] DEFENSE_BONUS = new short[] { 0, 0, 50, 0, 100, 50, 200, 0, 0, 50, 50, 0, 100, 0, 50,
			0, 50, 200, 0, 0, 50, 0, 0, 0, 100, 0, 50, 100, 0, 0, 0, 100, 200, 200, 0, 100 };

	// food
	private static final byte[] FOOD = new byte[] { 0, 0, 1, 2, 1, 1, 0, 1, 1, 2, 1, 1, 1, 3, 3, 3, 1, 0, 1, 3, 1, 2,
			1, 3, 2, 2, 3, 2, 2, 4, 0, 1, 0, 0, 3, 1 };

	// resource
	private static final byte[] PRODUCTION = new byte[] { 0, 1, 2, 0, 0, 0, 1, 0, 1, 0, 0, 0, 2, 0, 2, 0, 0, 1, 3, 1,
			4, 0, 1, 0, 0, 1, 0, 2, 3, 1, 2, 3, 2, 2, 2, 5 };

	// resource bonus
	private static final short[] PRODUCTION_BONUS = new short[] { 0, 0, 0, 50, 0, 0, 0, 0, 0, 50, 0, 50, 0, 0, 0, 0, 0,
			0, 0, 0, 0, 0, 0, 50, 0, 0, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0 };

	// trade
	private static final byte[] TRADE = new byte[] { 0, 0, 0, 0, 0, 0, 0, 2, 0, 1, 0, 0, 0, 2, 0, 0, 4, 6, 0, 0, 0, 0,
			0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 6, 0, 0 };

	// TODO : verifier la suite !

	// mining transformation
	private static final byte[] MINING_TRANSFORMATION = { -1, TerrainType.DESERT_M, -1, TerrainType.FOREST,
			TerrainType.HILLS_M, TerrainType.FOREST, TerrainType.MOUNTAINS_M, -1, TerrainType.FOREST, -1,
			TerrainType.FOREST, -1, TerrainType.COAL_M, -1, -1, -1, TerrainType.GAME_TUNDRA, TerrainType.GOLD_M,
			TerrainType.GAME_FOREST, TerrainType.OASIS_M, TerrainType.GAME_FOREST, -1, TerrainType.DESERT_M,
			TerrainType.FOREST, TerrainType.HILLS_M, TerrainType.FOREST, -1, TerrainType.COAL_M,
			TerrainType.GAME_FOREST, TerrainType.OASIS_M, -1, -1, -1, -1, -1, -1 };

	// mining cost (turns)
	private static final byte[] MINING_COST = new byte[] { -1, 5, -1, 10, 10, 15, 10, -1, 15, -1, 15, -1, 10, -1, -1,
			-1, 15, 10, 15, 5, 15, -1, 5, 10, 10, 15, -1, 10, 15, -1, 5, 10, 10, 10, 5, 10 };

	// irrigation transformation
	private static final byte[] IRRIGATION_TRANSFORMATION = { -1, TerrainType.DESERT_I, TerrainType.PLAINS,
			TerrainType.GRASSLAND_I, TerrainType.HILLS_I, TerrainType.GRASSLAND, -1, -1, TerrainType.PLAINS_I,
			TerrainType.RIVERS_I, TerrainType.GRASSLAND, -1, TerrainType.COALS_I, -1, TerrainType.HORSES, -1,
			TerrainType.GRASSLAND, -1, TerrainType.HORSES_I, TerrainType.OASIS_I, TerrainType.GRASSLAND, -1, -1, -1,
			-1, -1, -1, -1, -1, -1, DESERT_I, HILLS_I, -1, -1, OASIS_I, COALS_I };

	// irrigation cost (turns)
	private static final byte[] IRRIGATION_COST = { -1, 5, 5, 5, 10, 15, -1, -1, 5, 10, 15, 5, 10, -1, 5, 5, 15, -1, 5,
			5, 15, -1, 5, 5, 10, 5, 10, 5, 5, 5, 5, 10, -1, -1, 5, 10 };

	private static final String[] NAMES = { "Artic", "Desert", "Forest", "Grassland", "Hill", "Jungle", "Mountains",
			"Ocean", "Plains", "Rivers", "Swamp", "Tundra", "Coal (Hills)", "Fish (Ocean)", "Game (FOREST)",
			"Game (Tundra)", "Gems (Jungle)", "Gold (Mountains)", "Horses (Plains)", "Oasis (Desert)", "Oil (Swamp)",
			"Seals (Arctic)", "Desert (I)", "Grassland (I)", "Hills (I)", "Plains (I)", "Rivers (I)", "Coal (I)",
			"Horses (I)", "Oasis (I)", "Desert (M)", "Hills (M)", "Mountains (M)", "Gold (M)", "Oasis (M)", "Coal (M)" };

	private static Image[] imagesCache = new Image[TerrainType.SIZE];

	public static final byte[] SPECIAL_RESOURCES = { COAL, FISH, GAME_FOREST, GAME_TUNDRA, GEMS, GOLD, OASIS, OIL,
			SEALS };

	private TerrainType() {
		// no constructor
	}

	public static String getName(final byte id) {
		return NAMES[id];
	}

	public static byte getMPC(final byte id) {
		return MOVEMENT_COST[id];
	}

	public static short getDB(final byte id) {
		return DEFENSE_BONUS[id];
	}

	public static byte getPP(final byte id) {
		return PRODUCTION[id];
	}

	public static byte getFood(final byte id) {
		return FOOD[id];
	}

	public static short getPPB(final byte id) {
		return PRODUCTION_BONUS[id];
	}

	public static byte getTP(final byte id) {
		return TRADE[id];
	}

	public static byte getIrrigationTransformation(final byte id) {
		return TerrainType.IRRIGATION_TRANSFORMATION[id];
	}

	public static byte getIrrigationCost(final byte id) {
		return TerrainType.IRRIGATION_COST[id];
	}

	public static byte getMiningTransformation(final byte id) {
		return TerrainType.MINING_TRANSFORMATION[id];
	}

	public static byte getMiningCost(final byte id) {
		return TerrainType.MINING_COST[id];
	}

	public static Image getImage(final byte type) {
		if (imagesCache[type] == null) {
			StringBuffer sb = new StringBuffer();
			sb.append("/images/terrain_");
			sb.append(type);
			sb.append(".png");
			try {
				imagesCache[type] = Image.createImage(sb.toString());
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		return imagesCache[type];
	}

	public static boolean isOcean(final Terrain terrain) {
		return (terrain.type == OCEAN || terrain.type == FISH);
	}

	public static String toString(final byte id) {
		StringBuffer sb = new StringBuffer();
		sb.append("TerrainType[id=").append(id).append(", name='").append(getName(id)).append("', mpc=").append(
				getMPC(id)).append(", db=").append(getDB(id)).append(", fp=").append(getFood(id)).append(", rp=")
				.append(getPP(id)).append(", ppb =").append(getPPB(id)).append(", tp=").append(getTP(id)).append("]");
		return sb.toString();
	}
}
